「Git 介紹」Ch1: 什麼是 git rebase
最近自己對 git 的概念又整理了一下,先來介紹一下 git rebase

一. (What?) git rebase 可以做什麼 ?
除了 git merge 的另一種選擇
- merge 的常見三種方式:
git rebase,git merge,git cherry-pick- 一般做 merge 常見大概會有 rebase、merge、cherry-pick,這篇只先針對 rebase 做分享,rebase 可以做的事情算是滿多的。
- 與 git merge 的差別 ?
- 最主要在使用
git merge的時候,如果你有注意,其實都會再產生一個做 merge 這件事情的 commit,在git log --graph --all線圖上就不會是線性,線會轉彎然後合起來,最常見的情況是會產生小耳朵(小耳朵link)。然而在使用git rebase做 merge 時,它會是用接點的方式接在前面,rebase 顧名思義,重新定義 base(它的根),而當然實際 git 的實作, 不是單純拿原本的 commit 接上去,其實是複製了一份過去,SHA-1 值也是重新產生,是會改變的。
- 最主要在使用
有一個狀況 git merge 還是會保持一條線
(除非parent branch 的 commit 始終包含在 child branch 裡,parent branch 從來沒變更過,現在要把 parent 的進度更新成 child 的進度,這時候的 merge 會走 ff(fast-forward),也就是說不會產生額外的 commit,但這裡不討論這個,先假設 branch 間已經有分歧了,也是合作比較常見的狀況)。
如果在上述情況下 git merge 不想走 ff 可以
git merge --no-ff這樣一定會產生一個 commit, git 會請你再留一個 commit message。
二. 以下分享 git rebase, git merge 的差異
Ⅰ. 先來看 git merge,接下來藉由圖片和實例讓大家參考:
如果是 git merge 的情況:


- 目前我在
master加了add 01 projectcommit 接著在mastercommit 完後,建了一個分支add-02project,並 commit 了三次,停在feat: add 02.js,接著我繼續從add-02project分支建了add-03project分支,並 commit 一次feat: add 03.html,然後我回頭從master建add-04project分支 commit 一次feat: add 04.html,以上都只是我亂建的不重要,只是為了講解一下。
接下來重點是我想讓
add-04projectbranch 與add-03projectbranch 做 merge,
這裡如果我先做git merge:
- 目前 HEAD 在 add-04project,下指令
$ git merge add-03project
意思是 : merge branch
add-03projectinto branchadd-04project
接著,

你會看到線圖產生變化,多了一個 commit
cbcfe7b是 for merge 的,然後線圖也還是原本的線,只是接在一起了。
Ⅱ. 那現在來看如果使用 git rebase
- 原本的情況和圖1一樣,HEAD 一樣在
add-04projectbranch :
在這裡下
$ git rebase add-03project
字面意思是請幫我把我當前的 branch 的根換成
add-03projectbranch,所以實際上它會把當前 branch 進度複製接到add-03projectbranch 上,這時候會呈現如下:

- 會發現變成一條線了,且
add-04projectcommit 內容也都在,但 SHA-1 會重新計算。
三. rebase 反悔了怎麼辦:
git reset --hard <SHA-1值>
記得在使用 git rebase 的時候,如果反悔了剛剛的操作,不能用
git reset --hard HEAD^做相對路徑切換, 它是不會切回原樣的,要記得直接用絕對路徑切換,下git reflog看想切回去的地方,然後下git reset --hard <SHA-1值>也就是直接放 commit ID,或著是 reflog 上的 HEAD@{x},git reset --hard HEAD@{x}
|
|
四. git rebase -i (會進入 rebase 的互動模式,之後分享一下)
- 我把它稱作小小時光機,但就像 Back to the Future 演的那樣,很酷也容易不小心出問題。
- 可以做滿多事,但也要注意有時會更動到歷史紀錄,在多人協作專案,更是要小心操作。
五. (Why?) 為什麼需要 git rebase
先說結論:
- 直接先說我自己認為的結論,
git rebase只是工具,不管是 git merge、git rebase 還是其他 git 指令,其實都是因應情況、團隊開發模式等情況下,去做合理使用,只要在合適的情況使用 rebase 我相信是沒問題的,使用 rebase 有時可以讓專案的進度 (commit 顆粒) 更清晰。
那什麼是合適的情況 ? :
以下情況我根據自身經驗認為會使用或是可以使用:
1. 遠端 master(main) branch 的 code 進度更新了, 這時候自己的分支開發了一個功能,準備推上去,可以使用 rebase 讓自己的 branch 進度更新,最後再推上去自己的分支
$ git fetch upstream
$ git rebase upstream/master
$ git push origin 自己的 branch
2. 同理更新自己的 fork repo:
$ git checkout master
$ git fetch upstream
$ git rebase upstream/master
$ git push origin master
3. 整理 git 歷史紀錄,可以修改、合併、變更、刪除等等..
# 使用互動模式
$ git rebase -i <SHA-1>
The End:
Review:
git rebase與git merge的差異git rebase反悔如何處理git rebase使用時機的取捨- 在團隊協作中善用工具,follow 大家的共識